package com.dictionary.cn.core.dictionaryservice.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.springframework.context.annotation.Scope;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.stereotype.Service;

import com.dictionary.cn.core.FilterProperty;
import com.dictionary.cn.core.TreeDictionaryService;
import com.dictionary.cn.core.dictionaryservice.base.BaseDictionaryService;
import com.dictionary.cn.core.dictionaryservice.config.TreeDictionaryCache;
import com.dictionary.cn.core.dictionaryservice.dcitionarybean.TreeDictionary;

@Service("treeDictionaryService")
@Scope("prototype")
public class TreeDictionaryServiceImpl extends BaseDictionaryService<TreeDictionary> implements TreeDictionaryService<TreeDictionary> {
    
    /**
     * 树的缓存 解决缓存不同步的问题
     */
    private TreeDictionaryCache treeDictionaryCache;
    
    public void flush() {
        this.load(this.type, this.param);
    }

    public List<TreeDictionary> getAll(FilterProperty<TreeDictionary> filterProperty) {
        if(filterProperty == null){
            return new ArrayList<TreeDictionary>(this.treeDictionaryCache.kvCache.values());
        }else{
           List<TreeDictionary> resultDicList = new ArrayList<TreeDictionary>();
           for(TreeDictionary dic : this.treeDictionaryCache.kvCache.values()){
               if(filterProperty.filter(dic)){
                   resultDicList.add(dic);
               }
           }
           return resultDicList;
        }
    }

    public List<TreeDictionary> getChildren(String parent,
            FilterProperty<TreeDictionary> filterProperty) {
        
        List<TreeDictionary> resultList = null;
        if(parent == null){
            resultList = this.treeDictionaryCache.rootList;
        }else{
            resultList = this.treeDictionaryCache.treeCache.get(parent);
            if(resultList == null){
                resultList = new ArrayList<TreeDictionary>();
            }
        }
        
        if(filterProperty != null){
           List<TreeDictionary> tempDicList = new ArrayList<TreeDictionary>();
           for(TreeDictionary dic : resultList){
               if(filterProperty.filter(dic)){
                   tempDicList.add(dic);
               }
           }
           resultList = tempDicList;
        }
        
        return resultList;
    }

    public TreeDictionary getDicByKey(String key) {
        return this.treeDictionaryCache.kvCache.get(key);
    }

    public void load(String type,String treeSql) {
        this.param = treeSql;
        this.type = type;
        if(StringUtils.isBlank(this.param)){
            throw new RuntimeException("树形字典的参数不能为空");
        }
        List<TreeDictionary> allTreeDics = this.jdbcTemplate.query(this.param, BeanPropertyRowMapper.newInstance(this.getRowMapperClass()));
        
        Map<String, TreeDictionary> tempKvCache = new HashMap<String, TreeDictionary>();
       
        
        //第一遍 首先将所有的字典放入到一个缓存map中
        for(TreeDictionary dic : allTreeDics){
            if(dic.getKey() == null){
                throw new RuntimeException("字典类型【"+ type +"】 有的key为空");
            }
            tempKvCache.put(dic.getKey(), dic);
        }
        //第二遍 构造树形关系
        Map<String, List<TreeDictionary>> tempTreeCache = new  HashMap<String, List<TreeDictionary>>();
        List<TreeDictionary> tempRootList = new ArrayList<TreeDictionary>();
        for (TreeDictionary dic : allTreeDics) {

            if (dic.getParent() == null) {
                tempRootList.add(dic);
            } else {
                List<TreeDictionary> children =  tempTreeCache.get(dic.getParent());
                if(children == null){
                    children = new ArrayList<TreeDictionary>();
                    tempTreeCache.put(dic.getParent(), children);
                }
                children.add(dic);
            }
        }
        
        TreeDictionaryCache tempTreeDictionaryCache = new TreeDictionaryCache();
        tempTreeDictionaryCache.kvCache = tempKvCache;
        tempTreeDictionaryCache.rootList = tempRootList;
        tempTreeDictionaryCache.treeCache = tempTreeCache;
        
        this.treeDictionaryCache = tempTreeDictionaryCache;
    }
    
}
